package cn.edu.lingnan.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;

import okio.BufferedSource;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * DeepSeek API 客户端工具类，专注于发送请求和接收响应。
 */
public class DeepSeekClient {
    private static final String BASE_URL = "https://api.deepseek.com";


    private static final OkHttpClient client = new OkHttpClient()
            .newBuilder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .build();

    private final String apiKey ="sk-a449871580604953897b9107a164064e";

    public DeepSeekClient( ) {
     }

    /**
     * 发送请求，默认使用流式传输。
     *
     * @param messages 消息列表
     * @param callback 流式数据回调接口
     * @throws IOException 如果请求失败
     */
    public void sendRequest(JSONArray messages, StreamingCallback callback) throws IOException {
        sendRequest(messages, true, callback);
    }

    /**
     * 发送请求，支持流式和非流式传输。
     *
     * @param messages   消息列表
     * @param isStreaming 是否使用流式传输
     * @param callback    流式数据回调接口（非流式传输时可传 null）
     * @throws IOException 如果请求失败
     */
    public void sendRequest(JSONArray messages, boolean isStreaming, StreamingCallback callback) throws IOException {
        JSONObject requestBody = buildRequestBody(messages, isStreaming);
        Request request = buildRequest(requestBody);

        if (isStreaming) {
            sendStreamingRequest(request, callback);
        } else {
            String response = sendNonStreamingRequest(request);
            if (callback != null) {
                callback.onData(response); // 非流式传输时，一次性返回完整数据
                callback.onComplete(response);
            }
        }
    }

    /**
     * 发送非流式请求，一次性获取完整响应。
     *
     * @param request HTTP 请求
     * @return 完整的响应内容
     * @throws IOException 如果请求失败
     */
    private String sendNonStreamingRequest(Request request) throws IOException {
        String content="";
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            JSONObject chunk = JSON.parseObject(response.body().string());
            if (chunk.containsKey("choices")) {
                JSONObject delta = chunk.getJSONArray("choices")
                        .getJSONObject(0)
                        .getJSONObject("message");
                if (delta.containsKey("content")) {
                     content = delta.getString("content");

                }
            }


        }
        return content;
    }

    /**
     * 发送流式请求，逐块接收并处理数据。
     *
     * @param request  HTTP 请求
     * @param callback 流式数据回调接口
     * @throws IOException 如果请求失败
     */
    private void sendStreamingRequest(Request request, StreamingCallback callback) throws IOException {

        StringBuilder assistanceresp = new StringBuilder();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

            BufferedSource source = response.body().source();
            while (!source.exhausted()) {

                String line = source.readUtf8Line();

                if (line != null && !line.isEmpty()) {
                    if (line.startsWith("data: ")) {
                        String json = line.substring(6).trim();
                        if (json.equals("[DONE]")) {
                            callback.onComplete(assistanceresp.toString());
                            break;
                        }
                        JSONObject chunk = JSON.parseObject(json);
                        if (chunk.containsKey("choices")) {
                            JSONObject delta = chunk.getJSONArray("choices")
                                    .getJSONObject(0)
                                    .getJSONObject("delta");
                            if (delta.containsKey("content")) {
                                String content = delta.getString("content");
                                assistanceresp.append(content);
                                callback.onData(content);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 构建请求体。
     *
     * @param messages 消息列表
     * @param stream   是否启用流式传输
     * @return 请求体 JSON 对象
     */
    private JSONObject buildRequestBody(JSONArray messages, boolean stream) {
        JSONObject requestBody = new JSONObject();
        requestBody.put("model", "deepseek-chat");
        requestBody.put("messages", messages);
        requestBody.put("stream", stream); // 确保启用流式传输
        return requestBody;
    }

    /**
     * 构建 HTTP 请求。
     *
     * @param requestBody 请求体 JSON 对象
     * @return 构建好的 HTTP 请求
     */
    private Request buildRequest(JSONObject requestBody) {
        RequestBody body = RequestBody.create(requestBody.toJSONString(), MediaType.parse("application/json"));
        return new Request.Builder()
                .url(BASE_URL + "/chat/completions")
                .post(body)
                .addHeader("Authorization", "Bearer " + apiKey)
                .build();
    }

    /**
     * 流式数据回调接口，用于处理流式传输的数据。
     */
    public interface StreamingCallback {
        /**
         * 当接收到流式数据时调用。
         *
         * @param data 接收到的数据块
         */
        void onData(String data);

        /**
         * 当流式传输完成时调用。
         */
        void onComplete(String data);


    }
}
